<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>详解继承</title>
</head>
<body>
    
</body>
</html>

<script>
    //方法继承
    // function User(name){
    //     this.name = name;
    // }

    // function Admin(name){
    //     //属性继承
    //     User.call(this,name);
    //     // this.name = name;
    // }

    // // Admin.prototype = Object.create(User.prototype);

    // let hd = new Admin('aa');
    // console.log(hd)

    // class User{
    //     constructor(name){
    //         this.name = name;
    //     }
    // }

    // class Admin extends User{
    //     constructor(name){
    //         //这里使用super  就相当于调用了父类的构造方法   所以相当于在这里执行了   this.name = name  也就是进行了属性赋值
    //         super(name);
    //     }
    // }


    // let hd = new Admin("后盾人");
    // console.log(hd);


    //继承原理

    //要说明的一点是 因为方法是被所有的实例化所调用的  所以在原型链上
    //但是每个属性都是属于自己对象的   所以在当前对象上

    //class继承内部使用的是原型继承
    // class User{
    //     show(){
    //         console.log('User.show');
    //     }
    // }

    // class Admin extends User{
    //     info(){
    //         this.show();
    //     }
    // }


    // let admin = new Admin();
    // console.log(admin);


    //方法继承
    //两个要点   1:子类的构造函数中必须执行父类的构造函数  (2)父类的方法必须使用super.show()来进行调用
    // class Person{
    //     constructor(name){
    //         this.name = name;
    //     }
    //     show(){
    //         return `后盾人会员:${this.name}`;
    //     }
    // }

    // class User extends Person{
    //     //继承的时候必须在子类扥构造函数中调用super()执行父类构造函数
    //     constructor(name){
    //         super(name);
    //     }
    //     run(){
    //         //执行父类的方法
    //         return super.show();
    //     }
    // }

    // const xj = new User("向军");
    // console.dir(xj.run());


    //可以使用extends继承表达式 返回的类
    // function controller(){
    //     return class{
    //         show(){
    //             console.log('user.show');
    //         }
    //     }
    // }

    // class Admin extends controller{
    //     info(){
    //         this.show();
    //     }
    // }

    // let hd = new Admin();
    // console.dir(hd.prototype.show());



    //super表示从原型中执行方法
    //super一直指向当前对象

    // let user = {
    //     name : "user",
    //     show(){
    //         return this.name;
    //     }
    // };

    // let admin = {
    //     //改变admin对象的原型
    //     __proto__ : user,
    //     name : "admin",
    //     show(){
    //         return this.__proto__.show();
    //     }
    // };

    // console.log(admin.show());

    //为了解决以上问题，需要在调用父类方法的时候传递this
    


    // let user = {
    //     name : "user",
    //     show(){
    //         return this.name;
    //     }
    // };

    // let admin = {
    //     __proto__ : user,
    //     name : "admin",
    //     show(){
    //         return this.__proto__.show.call(this);
    //     }
    // };

    // console.log(admin.show());

    //上面的结果看似正常，但如果是多层继承的话，就会出现新的问题

    //因为始终传递的是当前对象的this  会造成this原型循环调用

    // let common = {
    //     show(){
    //         console.log('common.init');
    //     }
    // };

    // let user = {
    //     __proto__ : common,
    //     name : 'user',
    //     show(){
    //         return this.__proto__.show.call(this);
    //     }
    // };

    // let admin = {
    //     __proto__ : user,
    //     name : 'admin',
    //     get(){
    //         return this.__proto__.show.call(this);
    //     }
    // };


    // console.log(admin.get());

    //使用super调用，在所有继承中  this始终为调用对象

    //super是用来查找当前对象的原型，而不像上面使用this查找原型造成死循环
    //也就是说吧原型查询方法的事情交给了super()  this只是查询当前对象


    //总结   super()调用中   this指代的是当前调用它的对象
    // let common = {
    //     show(){
    //         return this.name;
    //     }
    // };

    // let user = {
    //     __proto__ : common,
    //     name : 'user',
    //     show(){
    //         return super.show();
    //     }
    // };

    // let admin = {
    //     __proto__ : user,
    //     name : "admin",
    //     get(){
    //         return super.show()
    //     }
    // };


    // console.log(admin.get());



    //super只能在类或者对象的方法中使用，而不能在函数中使用
    // let user = {
    //     name : "user",
    //     show(){
    //         return this.name;
    //     }
    // };

    // let admin = {
    //     __proto__ : user,
    //     name : 'admin',
    //     get:()=> {
    //         return super.show();
    //     }
    // };

    // console.log(admin.get());
    //对象方法   和方法是不一样的

    
   

</script>